Skip to content

Trim pre-1.0 legacy baggage#1793

Open
chubes4 wants to merge 6 commits intomainfrom
remove-legacy-migrations
Open

Trim pre-1.0 legacy baggage#1793
chubes4 wants to merge 6 commits intomainfrom
remove-legacy-migrations

Conversation

@chubes4
Copy link
Copy Markdown
Member

@chubes4 chubes4 commented May 5, 2026

Summary

Pre-1.0 Data Machine accumulated a chain of persisted-shape migrations,
deploy-window cleanup hooks, and a few code paths named "legacy" that
were actually current behavior. None of that has to be carried forward
forever. This branch trims the fat and keeps only the current contracts.

Four focused commits:

  1. Drop pre-1.0 data-shape migrations. Delete the entire
    migration chain plus their smokes. Keep only the current deploy-time
    schema ensures (bundle artifacts, processed-item claim columns,
    pending-action table) so an in-place plugin update without an
    activation toggle still gets the current schema. Also drops the
    init-priority "run full activation on every `DATAMACHINE_VERSION`
    bump" hook, the activation-time SiteContext/log-level option scrubs,
    and the `uninstall.php` deletes for old per-provider auth options
    and `chubes_ai_*` user_meta. `FlowStepConfig::normalizeHandlerShape`
    stops cross-inferring between scalar and plural handler shapes;
    canonical only.
  2. Drop bounded pre-1.0 runtime shims. Remove
    `SystemAgentServiceProvider`'s `LEGACY_DAILY_MEMORY_HOOK`,
    `LEGACY_TASK_HANDLE_HOOK`, and `LEGACY_RETENTION_HOOKS` plus the
    per-request Action Scheduler unschedule pass. Remove
    `OAuth2Handler::verify_state`'s plain-string transient fallback,
    `TaskScheduler`'s pre-0.82 `batch_id` lookup path,
    `Chat::ensure_mode_column`'s `context`/`agent_type` rename
    branch, and the v1 webhook auth doc/normalization comments.
  3. Rename misleading 'legacy' identifiers in active runtime code.
    These were named legacy but are the current contract:
    • `AgentBundleLegacyAdapter` → `AgentBundleArrayAdapter` (translates
      between `AgentBundleDirectory` and the runtime array shape; both
      are current Data Machine).
    • `ToolExecutionCore::executeLegacyTool` → `executeClassMethodTool`
    • `RequestBuilder::normalizeLegacy{ToolSchema,RequiredFlags}`
      → `normalize{ToolSchema,RequiredFlags}`
    • `DataMachineToolAccessPolicy::passesLegacyChatGate` → `passesChatGate`
    • `AgentRegistry::ensure_legacy_fired` →
      `ensure_datamachine_registration_fired`
      No behavior change.
  4. Drop pending-action legacy top-level fields.
    `PendingActionHelper::stage()` no longer mirrors `kind`, `summary`,
    `preview`, `resolve_with`, `resolve_params`, `instruction`,
    `expires_at` at the top level. Successful staging returns the
    Agents API `approval_required` envelope plus only `staged: true`
    and `action_id` for caller ergonomics. `PendingActionStore`'s
    `row_to_payload` no longer ships a `preview` alias alongside
    `preview_data`. Content abilities (`EditPostBlocksAbility`,
    `ReplacePostBlocksAbility`, `InsertContentAbility`) surface their
    own `kind`/`preview` since they already know both.

What didn't change

  • The Agents API bridges (`PendingActionStoreAdapter`,
    `PendingActionResolverAdapter`, `DataMachineToolAccessPolicy`)
    remain — they are clean wraps of Agents API contracts, not legacy.
  • The seams covering responsibilities Agents API doesn't own
    (`ConversationStoreFactory`, `AgentRegistry` registration bridge,
    `DataMachineToolRegistrySource`) remain — touching those is a
    responsibility-allocation decision, not cleanup.
  • Class/method tool execution (`executeClassMethodTool`) stays. Most
    Data Machine tools still register through `class`/`method`. Switching
    to ability-only is a separate scope.
  • `PendingActionStore`'s transient fallback path stays (smoke tests
    rely on it).
  • WP-CLI singular/plural aliases (`flow` vs `flows`) stay.

Validation

`php -l` clean over every changed file. Targeted smokes all pass:

Smoke Result
`migration-runtime-smoke` 16/16
`system-task-config-passthrough-smoke` 30/30
`ai-enabled-tools-smoke` 6/6
`retention-system-tasks-smoke` 68/68
`wp-ai-client-provider-admin-smoke` 28 assertions
`task-scheduler-batch-parent-link-smoke` 17/17
`agent-bundler-directory-adapter-smoke` 40/40
`datamachine-package-artifacts-smoke` 19/19
`agent-bundle-extension-artifacts-smoke` 23/23
`agent-bundle-portable-update-smoke` 36/36
`wp-ai-client-runtime-gate-smoke` 0 failures
`tool-executor-ability-native-smoke` 19/19
`pending-action-helper-approval-envelope-smoke` rewritten + passing

`pending-actions-agents-api-contract-smoke` and
`wp-ai-client-tool-schema-smoke` fail on this branch the same way they
fail on `origin/main` (missing `WordPressWorkspaceScope`, multimodal
passthrough). Both reproduced on baseline before this branch's edits.

Tests deleted with their corresponding migrations:

  • `agent-call-migration-smoke.php`
  • `agent-config-model-shape-migration-smoke.php`
  • `handler-slug-scalar-migration-smoke.php`
  • `queue-mode-collapse-smoke.php`
  • `queue-payload-split-smoke.php`
  • `settings-mode-models-migration-smoke.php`
  • `webhook-auth-v2-migration-smoke.php`
  • `Unit/Migrations/PostPipelineMetaMigrationTest.php`

Upgrade note

Sites currently running an older Data Machine that have not yet booted
under any version that ran the dropped migrations will keep their
old persisted shape and the new code will read it as malformed. The
expectation is that every supported install has already booted under
recent code, since each migration was idempotent and ran on every
`DATAMACHINE_VERSION` bump via the deferred runtime hook. If a site
is upgrading from much older code, run an intermediate version first.

AI assistance

  • AI assistance: Yes
  • Tool(s): Claude Code (Opus 4.7)
  • Used for: Audited the codebase for legacy/migration/shim
    surfaces, drafted the four focused commits (deletions, renames,
    test rewrites, pending-action envelope cleanup), ran the targeted
    smokes locally. Chris reviewed the audit findings, set the policy
    (pre-1.0, no consumer compatibility kept), and made the
    scope decisions (which adapters are legacy vs gap-fillers).

chubes4 added 4 commits May 5, 2026 11:23
Pre-1.0 Data Machine accumulated a chain of persisted-shape migrations
(layered architecture move, agent_ping → system_task → agent_call,
handler_slug singular → plural → cardinality-aware, queue payload
split + queue_mode collapse, webhook auth v2, settings/agent model
shape, ai-http-client provider keys, redundant post pipeline meta,
update → upsert, etc). Carrying all of those forward forever is fat,
not contract — every site that has ever booted current code already
ran them.

Remove the entire migration chain plus its smokes. Keep only the
current deploy-time schema ensures (bundle artifacts, processed-item
claim columns, pending-action table) so an in-place plugin update
without a reactivation toggle still gets the current schema.

Activation: drop the init-priority "run full activation on every
DATAMACHINE_VERSION bump" hook and the legacy SiteContext/log-level
option scrubs that only existed to clean up after older versions.

uninstall.php: remove deletes for old per-provider auth options,
chubes_ai_* user_meta, and datamachine_log_level_* options.

FlowStepConfig::normalizeHandlerShape: stop cross-inferring between
scalar and plural handler shapes. Canonical only — single-handler
steps own handler_slug/handler_config, multi-handler steps own
handler_slugs/handler_configs.

PostTracking: drop comment referencing the deleted post-pipeline-meta
migration.

Tests: delete every migration-runtime smoke that pinned the old
chain. Rewrite tests/migration-runtime-smoke.php to assert the
current schema runtime exists and the deleted migrations are gone.
Removes the bounded compatibility branches that only existed to clean
up state from older Data Machine versions. None of these are public
contracts.

SystemAgentServiceProvider: drop LEGACY_DAILY_MEMORY_HOOK,
LEGACY_TASK_HANDLE_HOOK, and LEGACY_RETENTION_HOOKS plus the
manageRecurringTaskSchedules() Action Scheduler unschedule pass that
swept them on every request.

OAuth2Handler::verify_state: drop the plain-string transient
fallback that handled in-flight OAuth states from the deploy window
between transient formats. Structured array is the only shape now.

TaskScheduler::resolveParentJobId: drop the pre-0.82.0 batch_id
string lookup path. BatchScheduler always passes the parent job ID;
numeric strings from Action Scheduler are still accepted, the rest
is dropped. summarizeBatchJob also drops the legacy 'total' fallback.

Chat::ensure_mode_column: drop the rename branch for legacy
'context' / 'agent_type' columns and the legacy index drops. Mode
column is created fresh when missing.

WebhookAuthResolver / WebhookTrigger: drop the doc references to v1
hmac_sha256 + webhook_signature_* + webhook_secret normalization
that the deleted webhook-auth-v2 migration handled.

Tests updated to assert these branches are gone instead of
exercising them.
Several active runtime paths were named 'legacy' even though they are
the current contract:

- AgentBundleLegacyAdapter -> AgentBundleArrayAdapter
  (translates between the AgentBundler runtime array shape and the
  AgentBundleDirectory value objects; both are current Data Machine).
- ToolExecutionCore::executeLegacyTool -> executeClassMethodTool
- RequestBuilder::normalizeLegacy{ToolSchema,RequiredFlags}
  -> normalize{ToolSchema,RequiredFlags}
- DataMachineToolAccessPolicy::passesLegacyChatGate -> passesChatGate
- AgentRegistry::ensure_legacy_fired ->
  ensure_datamachine_registration_fired
- PendingActionHelper staged-action local var renamed
  $legacy_payload -> $staged_action_payload.

Also drops a few comments that called active code 'legacy
compatibility' when it is just current behavior.

No behavior change; tests updated for the new symbol names.
PendingActionHelper::stage was returning the Agents API approval
envelope plus a copy of every legacy Data Machine staged-action
field at the top level (kind, summary, preview, resolve_with,
resolve_params, instruction, expires_at). Pre-1.0, that mirroring
was just leaking the old contract through.

Successful stage() now returns the Agents API envelope plus only
two convenience fields:

  - staged    => true
  - action_id => 'act_...'

Everything else lives inside the envelope payload:
envelope.payload.pending_action carries kind/summary/preview/
creator/agent/metadata/timestamps; envelope.payload.resolve_with
plus resolve_params plus instruction tell the AI how to confirm
or reject. Failures still return array( 'staged' => false,
'error' => ..., 'error_code' => ... ).

PendingActionStore::row_to_payload no longer ships a 'preview'
alias alongside 'preview_data' — the canonical key is preview_data
on persisted payloads, and pending_action.preview on the value
object.

EditPostBlocksAbility, ReplacePostBlocksAbility, and
InsertContentAbility now own the kind/preview values they used
to inherit from the helper, since they already know both. They
still merge the staged envelope so the AI sees the full
approval_required envelope; the additional top-level fields are
DM-internal callsite ergonomics.

The pending-action helper smoke is rewritten to assert the
envelope-only contract.
@homeboy-ci
Copy link
Copy Markdown
Contributor

homeboy-ci Bot commented May 5, 2026

Homeboy Results — data-machine

Lint

lint — passed

ℹ️ Full options: homeboy docs commands/lint
Deep dive: homeboy lint data-machine --changed-since f117c0d

Test

test — passed

  • 811 passed
  • 3 skipped

ℹ️ Auto-fix lint issues: homeboy refactor data-machine --from lint --write
ℹ️ Collect coverage: homeboy test data-machine --coverage
ℹ️ Save test baseline: homeboy test data-machine --baseline
ℹ️ Pass args to test runner: homeboy test -- [args]
ℹ️ Full options: homeboy docs commands/test
Deep dive: homeboy test data-machine --changed-since f117c0d

Audit

audit — passed

  • test_coverage — 342 finding(s)
  • dead_code — 158 finding(s)
  • intra-method-duplication — 73 finding(s)
  • requested_detectors — 48 finding(s)
  • parallel-implementation — 31 finding(s)
  • repeated_literal_shape — 13 finding(s)
  • dead_guard — 9 finding(s)
  • Api — 6 finding(s)
  • field_patterns — 5 finding(s)
  • structural — 5 finding(s)
  • Total: 712 finding(s)

Deep dive: homeboy audit data-machine --changed-since f117c0d

Tooling versions
  • Homeboy CLI: homeboy 0.157.1+b3b528a8
  • Extension: wordpress from https://github.com/Extra-Chill/homeboy-extensions
  • Extension revision: a9f3e87
  • Action: Extra-Chill/homeboy-action@v2

chubes4 added 2 commits May 5, 2026 12:09
CI test boot ran AgentMaterializer::reconcile() before any
datamachine_* table existed because the previous version-bump path
(datamachine_maybe_run_migrations on init priority 5) re-ran the
full activation function and that called every create_table() pass.
Removing it left only the deferred runtime in
inc/migrations/runtime.php, which only ensured three tables
(bundle_artifacts, processed-item claims, pending-actions). Fresh
installs whose activation hook never fired (Homeboy Playground
test runner, deploy-in-place, manual rsync) ended up with a code
boot trying to read tables that did not exist.

Factor table creation out of datamachine_activate_for_site() into
a shared datamachine_ensure_all_tables() helper, and call it from
datamachine_run_schema_migrations() so the deferred plugins_loaded
runtime ensures every Data Machine table on a DATAMACHINE_VERSION
mismatch. dbDelta and the per-table column ensures are idempotent;
this is cheap to re-run. Activation still runs the same helper,
so behavior on activation is unchanged.

Also fixes phpcs alignment introduced by the FlowStepConfig
normalization rewrite — $handler_configs is one character longer
than the rest of the locals so the = column needed one extra space.
Ensure agent reconciliation can recover missing agent tables in test and deploy-in-place boots where activation did not run, while keeping the deferred schema runtime responsible for full table creation on version drift.

Update the image prompt refinement test to assert the current wp-ai-client prompt field, with messages as a fallback, and clean changed-file lint findings surfaced by Homeboy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant